<?php

require_once(PATH_CLASS.'base.class.php');
require_once(PATH_CLASS.'css.class.php');
require_once(PATH_CLASS.'js.class.php');

abstract class widget extends base{
  
  const CLASS_NAME        = 'widget';
  const C_WRAP_BEGIN      = 'begin';
  const C_WRAP_END        = 'end';
  const C_SCRIPT_WRAP     = 'scriptWrap';

  var $params             = array();
  var $linkedCss          = array();
  var $linkedWidgetCss    = array();
  var $linkedJs           = array();
  var $linkedWidgetJs     = array();
  
  static $allreadyLoaded  = array();
  
  public function getDefaults(){
    $ret = array();
    $ret[self::C_SCRIPT_WRAP]=self::C_WRAP_END;
    return $ret;
  }
  
  public function __construct($params) {
    
    $params = array_merge($this->getDefaults(),$params);
    
    $this->params = $params;
    
    if(!$this->isAuthorized()){
      throw new Exception("Non pas le droit");
    }
        
  }

  public function getTplPath(){
    $ret = PATH_TPL.'widgets/';
    return $ret;
  }
  
//  public function getWidgetTpl(){
//    $ret = $this->getTplPath();
//    $file = __FILE__;
//  }

    abstract function _render();
    protected abstract function _get_called_class();
    
    static function setLoaded($widgetName){
      self::$allreadyLoaded[$widgetName]=true;
    }
    
    static function isLoaded($widgetName){
      $ret=isset(self::$allreadyLoaded[$widgetName]);
      return $ret;
    }
    
    public function isAuthorized(){
      return true;
    }
    
    public function autoRenderCss(){
      return true;
    }
    
    public function autoRenderJs(){
      return true;
    }
    
    public function getStyle($style=array()){
      $parStyle=array();
      if(isset($this->params['style'])){
        $parStyle = $this->params['style'];
      }
      
      $style = array_merge($parStyle,$style);
      
      $styleStr=array();
      foreach($style as $prop=>$value){
        $styleStr[]=  sprintf('%s: %s',$prop,$value);
      }
      
      return join(';',$styleStr);
    }
    
    public function renderCss(){
      $class = $this->_get_called_class();
      css::addWidget("$class.css");
      
      foreach ($this->linkedCss as $file=>$void){
        css::addWidget($file);
      }
    }
    
    public function renderJs(){
      $class = $this->_get_called_class();
      js::addWidget("$class.js");
    }

    protected function _addTb(&$tab,$file){
      if(!isset($tab[$file])){
        $tab[$file] = true;
      }
    }
    
    public function addCss($file){
      $this->_addTb($this->linkedCss, $file);
    }

    public function addJs($file){
      $this->_addTb($this->linkedJs, $file);
    }
    
    public function addWidgetCss($file){
      $class = $this->_get_called_class();
      $file = "$class/$file";
      $this->_addTb($this->linkedWidgetCss, $file);
    }
    
    public function addWidgetJs($file){
      $class = $this->_get_called_class();
      $file = "$class/$file";
      $this->_addTb($this->linkedWidgetJs, $file);
    }
    
    public function getScriptWrap(){
      $ret=self::C_WRAP_END;
      if(isset($this->params[self::C_SCRIPT_WRAP])){
        $ret = $this->params[self::C_SCRIPT_WRAP];
      }
      return($ret);
    }
    
    public function getWrapperBegin(){
      $class        = get_class();
      $class        = $this->_get_called_class();
      $moreClass    = array();
      $moreClass[]  = $class;
      
      $params = $this->params;
      if(isset($params['type'])){
        $moreClass[]="$class-{$params['type']}";
      }

      if(isset($params['class'])){
        if(!is_array($params['class'])) $params['class'] = array($params['class']);
        
        if(count($params['class'])>0){
          $moreClass[]=join('',$params['class']);
        }
      }
      
      $begin[]=sprintf('<div class="mod widget %s" style="%s">',join(' ',$moreClass),$this->getStyle());
      
      if($this->getScriptWrap()==self::C_WRAP_BEGIN){
        $begin[]=$this->getScripts();
      } 

      return join('',$begin);
    }
    
    public function getScripts(){
      $scripts[]='<script>';
      $loadedClass = $this->_get_called_class();
      
      if(isset($this->type) && !empty($this->type)){
        $loadedClass .='/'.$this->type;
      }
      
      if(!self::isLoaded($loadedClass)){
        
        if($this->autoRenderJs()){
          foreach($this->linkedJs as $file=>$void){
            if(file_exists($file)){
              $scripts[]='com.lolita.utils.addScript("'.$file.'");';
            } 
          }

          foreach($this->linkedWidgetJs as $file=>$void){
            if(file_exists("js/widgets/".$file)){
              $scripts[]='com.lolita.utils.addWidgetScript("'.$file.'");';
            } 
          }
        }
        
        if($this->autoRenderCss()){
          foreach($this->linkedCss as $file=>$void){
            if(file_exists($file)){
              $scripts[]='com.lolita.utils.addStyleSheet("'.$file.'");';
            } 
          }

          foreach($this->linkedWidgetCss as $file=>$void){
            if(file_exists("css/widgets/".$file)){
              $scripts[]='com.lolita.utils.addWidgetStyleSheet("'.$file.'");';
            } 
          }
        }


      }
      
      if(count($scripts)==1){
        $scripts=array();
      } else {
        $scripts[]='</script>';
      }
      
      return join('',$scripts);

    }
    
    public function getWrapperEnd(){
      if($this->getScriptWrap()==self::C_WRAP_END){
        $end[]=$this->getScripts();
      }
      $end[]='</div>';
      
      return join('',$end);
    }

    public function renderTplFromFile($__file__,$pars,$addWrapper=true){
      
      if($addWrapper){
        $ret[] = $this->getWrapperBegin();
      }
      
      $ret[] = commun::getClassViewFromFile($__file__,$pars,'php_classe','class.php');
      
      if($addWrapper){
        $ret[] = $this->getWrapperEnd();
      }
      return join('',$ret);
    }

    static function render($widgetName,$params=array()){
    $file = PATH_CLASS."widgets/$widgetName.class.php";
    $ret='';
    if(file_exists($file)){
      require_once $file;
      try{
        /* @var $widget widget */
        $widget = new $widgetName($params);
      } catch(Exception $e){
        return '';
      }
      
      if($widget->autoRenderCss()){
        $widget->addCss("css/widgets.css");
        $widget->addCss("css/widgets/$widgetName.css");
      }

      if($widget->autoRenderJs()){
        $widget->addJs("js/widgets.js");
        $widget->addJs("js/widgets/$widgetName.js");
      }
      
      $ret = $widget->_render();
      
      if($widget->autoRenderCss()){
        $widget->renderCss();
      }
      
      if($widget->autoRenderJs()){
        $widget->renderJs();
      }
      
      self::setLoaded($widgetName);
      
    }
    return $ret;
  }
  
}

